#ifndef _SIMPLE_NODE_H_
#define _SIMPLE_NODE_H_

////////////////////////////////////////////////////////////////////////////////
// Includes
////////////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////////////
// Namespaces
////////////////////////////////////////////////////////////////////////////////

namespace Types {

////////////////////////////////////////////////////////////////////////////////
// Implementation
////////////////////////////////////////////////////////////////////////////////

/**
 *  Generic Simple Node (Not using arcs for linking nodes)
 */
template <typename TN = int>
class SimpleNode {

	public:

		/// Constructor
		SimpleNode(const TN & data)
		:	data(data)
		{}

		/// Creates a copy of the given instance
		SimpleNode(const SimpleNode<TN> & inst)
		:	data(inst.data),
			sub_nodes(inst.sub_nodes)
		{}
		
		/// Affectation operator
		SimpleNode & operator = (const SimpleNode<TN> & inst) {
			if (this != &inst) {
				this->data = inst.data;
				this->sub_nodes = inst.sub_nodes;
			}
			return *this;
		}

		/// Returns the data (read only)
		const TN & GetData() const { return this->data; }

		/// Returns the data
		TN & Data() { return this->data; }
		
		/// Returns the number of sub nodes
		const unsigned int GetNbSubNodes() const { return this->sub_nodes.size(); }

		/// Returns the required sub node (read only)
		const SimpleNode<TN> & GetSubNode(const unsigned int i) const { return this->sub_nodes[i]; }

		/// Returns the required sub node
		SimpleNode<TN> & SubNode(const unsigned int i) { return this->sub_nodes[i]; }

		/// Adds a sub node
		void AddSubNode(const SimpleNode<TN> & node) { this->sub_nodes.push_back(node); }
		
	protected:

		/// Node data
		TN data;

		/// Sub nodes of the current node
		std::vector< SimpleNode<TN> > sub_nodes;

};

////////////////////////////////////////////////////////////////////////////////
// Closing Namespaces
////////////////////////////////////////////////////////////////////////////////

}

////////////////////////////////////////////////////////////////////////////////

#endif
